/**
 * MinIO 文件管理页面
 * 提供文件列表、筛选、分页等能力
 */

import React, { useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { Container } from '@/components/ui/container';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  ResponsiveTable,
  ResponsiveTableHeader,
  ResponsiveTableRow,
  ResponsiveTableHead,
  ResponsiveTableCell,
  TableLoading,
  TableEmpty
} from '@/components/ui/responsive-table';
import { TableBody } from '@/components/ui/table';
import { Skeleton } from '@/components/ui/skeleton';
import {
  HardDrive,
  Filter,
  Download,
  Trash2,
  Search,
  RefreshCw,
  FileText,
  UploadCloud,
  Upload
} from 'lucide-react';
import { fileService } from '@/lib/api/services/file-service.js';
import { cn } from '@/lib/utils';

const FILE_TYPE_OPTIONS = [
  { label: '全部类型', value: 'all' },
  { label: '图片 (image)', value: 'image' },
  { label: '文档 (document)', value: 'document' },
  { label: 'Markdown', value: 'markdown' },
  { label: '头像 (avatar)', value: 'avatar' },
  { label: '封面 (cover)', value: 'cover' },
  { label: '其他 (other)', value: 'other' }
];

const ACCESS_POLICY_OPTIONS = [
  { label: '全部访问策略', value: 'all' },
  { label: '公开 (public)', value: 'public' },
  { label: '私有 (private)', value: 'private' },
  { label: '登录可访问 (authenticated)', value: 'authenticated' }
];

const formatFileSize = (size = 0) => {
  if (!size) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  let index = 0;
  let value = size;
  while (value >= 1024 && index < units.length - 1) {
    value /= 1024;
    index++;
  }
  return `${value.toFixed(value >= 10 ? 0 : 1)} ${units[index]}`;
};

const formatDateTime = (dateString) => {
  if (!dateString) return '-';
  return new Date(dateString).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  });
};

const DocFileManagerPage = () => {
  const [keyword, setKeyword] = useState('');
  const [bucketName, setBucketName] = useState('');
  const [fileType, setFileType] = useState('all');
  const [accessPolicy, setAccessPolicy] = useState('all');
  const [documentId, setDocumentId] = useState('');
  const [page, setPage] = useState(1);
  const [pageSize] = useState(20);
  const [showUploadDialog, setShowUploadDialog] = useState(false);
  const [selectedFile, setSelectedFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [uploadOptions, setUploadOptions] = useState({
    fileType: 'document',
    accessPolicy: 'private',
    fileCategory: '',
    documentId: ''
  });

  const {
    data: filesData,
    isLoading,
    error,
    refetch
  } = useQuery({
    queryKey: [
      'files',
      'list',
      keyword,
      bucketName,
      fileType,
      accessPolicy,
      documentId,
      page,
      pageSize
    ],
    queryFn: () =>
      fileService.getList({
        keyword,
        bucketName,
        fileType: fileType === 'all' ? '' : fileType,
        accessPolicy: accessPolicy === 'all' ? '' : accessPolicy,
        documentId,
        page,
        pageSize
      })
  });

  const files = filesData?.data || [];
  const meta = {
    page: filesData?.page || 1,
    pageSize: filesData?.pageSize || pageSize,
    total: filesData?.total || 0,
    totalPages: filesData?.totalPages || 0
  };

  const handlePageChange = (newPage) => {
    setPage(newPage);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

const handleDownload = async (file) => {
    try {
      const data = await fileService.getDownloadUrl(file.id);
      const url = data?.downloadUrl;
      if (!url) {
        window.alert('未能获取下载链接，请稍后重试');
        return;
      }
      window.open(url, '_blank', 'noopener,noreferrer');
    } catch (err) {
      window.alert(`下载失败：${err.message || '请稍后重试'}`);
    }
  };

  const filterBadgeText = useMemo(() => {
    const badges = [];
    if (bucketName) badges.push(`Bucket: ${bucketName}`);
    if (fileType && fileType !== 'all') badges.push(`类型: ${fileType}`);
    if (accessPolicy && accessPolicy !== 'all') badges.push(`策略: ${accessPolicy}`);
    if (documentId) badges.push(`关联文档: ${documentId}`);
    if (keyword) badges.push(`关键字: ${keyword}`);
    return badges.join('，');
  }, [bucketName, fileType, accessPolicy, documentId, keyword]);

  return (
    <Container>
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-3xl font-bold flex items-center gap-2">
            <HardDrive className="size-6 text-primary" />
            MinIO 文件管理
          </h1>
          <p className="text-muted-foreground mt-1">
            共 {meta.total} 个文件
            {filterBadgeText && (
              <span className="inline-block ml-2 text-xs text-muted-foreground/80">
                当前筛选：{filterBadgeText}
              </span>
            )}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Link to="/documentation">
            <Button variant="outline">
              返回文档列表
            </Button>
          </Link>
          <Button onClick={() => setShowUploadDialog(true)}>
            <Upload className="size-4 mr-2" />
            上传到 MinIO
          </Button>
          <Link to="/documentation/new">
            <Button>
              <UploadCloud className="size-4 mr-2" />
              上传文件
            </Button>
          </Link>
        </div>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>文件列表</CardTitle>
        </CardHeader>
        <CardContent>
          {/* 筛选区域 */}
          <div className="grid grid-cols-1 lg:grid-cols-5 gap-4 mb-6">
            <div className="col-span-1 lg:col-span-2 relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-gray-400" />
              <Input
                placeholder="搜索文件名或对象键..."
                value={keyword}
                onChange={(e) => {
                  setKeyword(e.target.value);
                  setPage(1);
                }}
                className="pl-10"
              />
            </div>

            <Input
              placeholder="Bucket 名称"
              value={bucketName}
              onChange={(e) => {
                setBucketName(e.target.value.trim());
                setPage(1);
              }}
            />

            <Select
              value={fileType}
              onValueChange={(value) => {
                setFileType(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <Filter className="size-4 mr-2" />
                <SelectValue placeholder="文件类型" />
              </SelectTrigger>
              <SelectContent>
                {FILE_TYPE_OPTIONS.map(option => (
                  <SelectItem key={option.label} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Select
              value={accessPolicy}
              onValueChange={(value) => {
                setAccessPolicy(value);
                setPage(1);
              }}
            >
              <SelectTrigger>
                <SelectValue placeholder="访问策略" />
              </SelectTrigger>
              <SelectContent>
                {ACCESS_POLICY_OPTIONS.map(option => (
                  <SelectItem key={option.label} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Input
              placeholder="关联文档ID"
              value={documentId}
              onChange={(e) => {
                setDocumentId(e.target.value);
                setPage(1);
              }}
            />
          </div>

          <div className="flex items-center justify-between mb-4">
            <div className="text-sm text-muted-foreground">
              支持按 Bucket、文件类型、访问策略等筛选
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={() => {
                  setKeyword('');
                  setBucketName('');
                  setFileType('all');
                  setAccessPolicy('all');
                  setDocumentId('');
                  setPage(1);
                }}
              >
                清除筛选
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => refetch()}
                title="刷新"
              >
                <RefreshCw className="size-4" />
              </Button>
            </div>
          </div>

          {/* 表格 */}
          <ResponsiveTable>
            <ResponsiveTableHeader>
              <ResponsiveTableRow>
                <ResponsiveTableHead>文件名</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>文件类型</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>Bucket</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>大小</ResponsiveTableHead>
                <ResponsiveTableHead hideOnTablet>访问策略</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>关联文档</ResponsiveTableHead>
                <ResponsiveTableHead hideOnMobile>上传时间</ResponsiveTableHead>
                <ResponsiveTableHead>操作</ResponsiveTableHead>
              </ResponsiveTableRow>
            </ResponsiveTableHeader>

            <TableBody>
              {isLoading ? (
                <TableLoading rows={6} columns={8} />
              ) : error ? (
                <ResponsiveTableRow>
                  <ResponsiveTableCell colSpan={8} className="text-center py-10">
                    <p className="text-destructive mb-4">
                      加载失败：{error.message}
                    </p>
                    <Button variant="outline" onClick={() => refetch()}>
                      重试
                    </Button>
                  </ResponsiveTableCell>
                </ResponsiveTableRow>
              ) : files.length === 0 ? (
                <TableEmpty
                  colSpan={8}
                  icon={FileText}
                  title="暂无文件"
                  description="上传文件或调整筛选条件后再试。"
                />
              ) : (
                files.map(file => (
                  <ResponsiveTableRow key={file.id}>
                    <ResponsiveTableCell className="font-medium">
                      <div className="flex flex-col">
                        <span className="line-clamp-1">{file.fileName}</span>
                        <span className="text-xs text-muted-foreground line-clamp-1">
                          {file.objectKey || file.filePath}
                        </span>
                      </div>
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnMobile className="text-sm text-muted-foreground">
                      {file.fileType || '-'}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnMobile className="text-sm text-muted-foreground">
                      {file.bucketName}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnTablet className="text-sm text-muted-foreground">
                      {formatFileSize(file.fileSize)}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnTablet className="text-sm text-muted-foreground capitalize">
                      {file.accessPolicy || '-'}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnMobile className="text-sm text-muted-foreground">
                      {file.documentId ? (
                        <Link
                          to={`/documentation/edit/${file.documentId}`}
                          className="text-primary hover:underline"
                        >
                          {file.documentId}
                        </Link>
                      ) : (
                        '-'
                      )}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell hideOnMobile className="text-sm text-muted-foreground">
                      {formatDateTime(file.createdAt)}
                    </ResponsiveTableCell>

                    <ResponsiveTableCell>
                      <div className="flex items-center gap-2">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => handleDownload(file)}
                        >
                          <Download className="size-4 mr-1" />
                          下载
                        </Button>
                        <Button
                          size="sm"
                          variant="ghost"
                          disabled
                          title="删除功能即将上线"
                        >
                          <Trash2 className="size-4" />
                        </Button>
                      </div>
                    </ResponsiveTableCell>
                  </ResponsiveTableRow>
                ))
              )}
            </TableBody>
          </ResponsiveTable>

          {/* 分页 */}
          {meta.totalPages > 1 && (
            <div className="flex items-center justify-between mt-6">
              <div className="text-sm text-muted-foreground">
                显示第 {(meta.page - 1) * meta.pageSize + 1} -{' '}
                {Math.min(meta.page * meta.pageSize, meta.total)} 条，共 {meta.total} 条
              </div>
              <div className="flex items-center gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => handlePageChange(meta.page - 1)}
                  disabled={meta.page === 1}
                >
                  上一页
                </Button>
                <div className="flex items-center gap-1">
                  {Array.from({ length: Math.min(meta.totalPages, 5) }, (_, index) => {
                    const pageNum =
                      meta.page <= 3 ? index + 1 : meta.page + index - 2;
                    if (pageNum < 1 || pageNum > meta.totalPages) {
                      return null;
                    }
                    return (
                      <Button
                        key={pageNum}
                        variant={pageNum === meta.page ? 'default' : 'outline'}
                        size="sm"
                        onClick={() => handlePageChange(pageNum)}
                        className="w-9"
                      >
                        {pageNum}
                      </Button>
                    );
                  })}
                </div>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => handlePageChange(meta.page + 1)}
                  disabled={meta.page === meta.totalPages}
                >
                  下一页
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {showUploadDialog && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-card border rounded-lg shadow-lg w-full max-w-lg p-6 space-y-4">
            <div className="flex items-center justify-between">
              <h2 className="text-xl font-semibold">上传文件到 MinIO</h2>
              <Button variant="ghost" size="sm" onClick={() => setShowUploadDialog(false)}>
                关闭
              </Button>
            </div>

            <div className="space-y-4">
              <div>
                <label className="text-sm font-medium mb-2 block">
                  选择文件
                </label>
                <div
                  className={cn(
                    "border-2 border-dashed rounded-lg p-6 text-center transition-colors",
                    selectedFile ? "border-primary bg-primary/5" : "border-muted-foreground/40 hover:border-primary/60"
                  )}
                  onDragOver={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                  }}
                  onDrop={(e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
                      setSelectedFile(e.dataTransfer.files[0]);
                      e.dataTransfer.clearData();
                    }
                  }}
                >
                  <input
                    type="file"
                    id="file-input"
                    className="hidden"
                    onChange={(e) => setSelectedFile(e.target.files?.[0] || null)}
                  />
                  <label htmlFor="file-input" className="cursor-pointer flex flex-col items-center gap-2">
                    <Upload className="size-10 text-muted-foreground" />
                    <div className="text-sm">
                      {selectedFile ? (
                        <>
                          <p className="font-medium">{selectedFile.name}</p>
                          <p className="text-xs text-muted-foreground mt-1">
                            {formatFileSize(selectedFile.size)}
                          </p>
                          <p className="text-xs text-muted-foreground mt-2">
                            点击或拖拽更换文件
                          </p>
                        </>
                      ) : (
                        <>
                          <p className="font-medium">点击或拖拽文件到此区域</p>
                          <p className="text-xs text-muted-foreground mt-1">
                            支持任意类型文件
                          </p>
                        </>
                      )}
                    </div>
                  </label>
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <label className="text-sm font-medium mb-2 block">
                    文件类型
                  </label>
                  <Select
                    value={uploadOptions.fileType}
                    onValueChange={(value) =>
                      setUploadOptions((prev) => ({ ...prev, fileType: value }))
                    }
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="选择文件类型" />
                    </SelectTrigger>
                    <SelectContent>
                      {FILE_TYPE_OPTIONS.filter(option => option.value !== 'all').map(option => (
                        <SelectItem key={option.value} value={option.value}>
                          {option.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div>
                  <label className="text-sm font-medium mb-2 block">
                    访问策略
                  </label>
                  <Select
                    value={uploadOptions.accessPolicy}
                    onValueChange={(value) =>
                      setUploadOptions((prev) => ({ ...prev, accessPolicy: value }))
                    }
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="选择访问策略" />
                    </SelectTrigger>
                    <SelectContent>
                      {ACCESS_POLICY_OPTIONS.filter(option => option.value !== 'all').map(option => (
                        <SelectItem key={option.value} value={option.value}>
                          {option.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <label className="text-sm font-medium mb-2 block">
                    文件分类（可选）
                  </label>
                  <Input
                    placeholder="doc-image / doc-attachment / user-avatar 等"
                    value={uploadOptions.fileCategory}
                    onChange={(e) =>
                      setUploadOptions((prev) => ({ ...prev, fileCategory: e.target.value }))
                    }
                  />
                </div>
                <div>
                  <label className="text-sm font-medium mb-2 block">
                    关联文档 ID（可选）
                  </label>
                  <Input
                    placeholder="输入文档ID"
                    value={uploadOptions.documentId}
                    onChange={(e) =>
                      setUploadOptions((prev) => ({ ...prev, documentId: e.target.value }))
                    }
                  />
                </div>
              </div>

              <div className="flex items-center justify-end gap-2">
                <Button
                  variant="outline"
                  onClick={() => {
                    setShowUploadDialog(false);
                    setSelectedFile(null);
                  }}
                >
                  取消
                </Button>
                <Button
                  onClick={async () => {
                    if (!selectedFile) {
                      window.alert('请先选择文件');
                      return;
                    }
                    try {
                      setUploading(true);
                      const payload = {
                        ...uploadOptions,
                        documentId: uploadOptions.documentId || undefined,
                        fileCategory: uploadOptions.fileCategory || undefined
                      };
                      await fileService.upload(selectedFile, payload);
                      window.alert('上传成功');
                      setShowUploadDialog(false);
                      setSelectedFile(null);
                      setUploading(false);
                      refetch();
                    } catch (err) {
                      setUploading(false);
                      window.alert(`上传失败：${err.message || '请稍后重试'}`);
                    }
                  }}
                  disabled={uploading}
                >
                  {uploading ? '上传中...' : '确认上传'}
                </Button>
              </div>
            </div>
          </div>
        </div>
      )}
    </Container>
  );
};

export default DocFileManagerPage;


